Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Backend] Record when Consent is Served #3777

Merged
merged 11 commits into from
Jul 13, 2023

Conversation

pattisdr
Copy link
Contributor

@pattisdr pattisdr commented Jul 11, 2023

Closes #3006

Description Of Changes

For consent reporting, and for other purposes like building gpp strings, we need records of whether consent was served, even if the user chose to not save any preferences.

We don’t necessarily record each time an API request is made to get consent, but instead whenever the components actually show something to the user. Therefore, add a new endpoint for the frontend to call when they serve consent via a particular component. Add new tables to store that consent was served. Update the requests that save preferences to optionally pass in the id where we served the preference to be able to calculate conversion in the future. When retrieving preferences for a given user embedded on notices, also return whether that notice was served.

Code Changes

Some new tables were added and several methods abstracted to share code between when saving preferences and recording that consent is served, as we track very similar details

  • Add new servednoticehistory to track every single time a version of a notice is served for consent reporting
  • Add new lastservednotice table to consolidate the last time a notice was served, across any version, for all the known identifies of a user
  • Add new column: privacypreferencehistory.served_notice_history_id to link the record between a notice being served, and the preferences being saved with respect to that notice
  • When getting experiences via the API with a fides user device id query param, add whether the current notice was served or an outdated version of the notice was served to the embedded notice response
  • Create a ConsentReportingMixin to share common fields between PrivacyPreferenceHistory and ServedNoticeHistory tables
  • Create upsert_last_saved_record to share common code between upserting a CurrentPrivacyPreference or a LastServedNotice record
  • Add new endpoints to save when consent was served, one for the privacy center, and one for banner/overlay: PATCH "/consent-request/{consent_request_id}/notices-served" and PATCH "/notices-served"
  • Generalized verify_privacy_notice_and_historical_records to share with multiple API endpoints
  • Generalized supplement_request_with_user_and_experience_details to share when saving preferences and the fact that notices were served. Both locations record a lot of information about the user.
  • Dry up classify_identities_for_privacy_center_consent_reporting to share with multiple locations

Steps to Confirm

  • nox -s dev -- shell
  • Get a valid experience id and notice history id from this response.
    • GET localhost:8080/api/v1/privacy-experience?region=us_ca
  • PATCH that the specific notice has been served. This is something the frontend will call when they serve notices in a component, by patching all the notice histories here in a list. If it's a banner, and no notices are shown, send all the notices that are in play here.
    PATCH http://localhost:8080/api/v1/notices-served
{
  "browser_identity": {
    "fides_user_device_id": "3e2e5f7c-5367-47d4-b672-9427626c71db"
  },
  "privacy_notice_history_ids": [
    "pri_52008ca3-406e-420f-8509-9429c73ef859"
  ],
  "privacy_experience_id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
  "user_geography": "us_ca",
  "acknowledge_mode": false,
  "serving_component": "overlay"
}
{
  "browser_identity": {
    "fides_user_device_id": "3e2e5f7c-5367-47d4-b672-9427626c71db"
  },
  "preferences": [
    {
      "privacy_notice_history_id": "pri_52008ca3-406e-420f-8509-9429c73ef859",
      "preference": "opt_in",
      "served_notice_history_id": "ser_e83dd23c-cc82-44bc-9046-824089f80e2e"
    }
  ],
  "policy_key": "default_consent_policy",
  "privacy_experience_id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
  "user_geography": "us_ca",
  "method": "button"
}
{
  "items": [
    {
      "region": "us_ca",
      "component": "overlay",
      "experience_config": {},
      "id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
      "created_at": "2023-07-06T13:28:35.171060+00:00",
      "updated_at": "2023-07-06T13:28:35.171060+00:00",
      "show_banner": true,
      "privacy_notices": [
        {
          "regions": [
            "us_ca"
          ],,
          "privacy_notice_history_id": "pri_52008ca3-406e-420f-8509-9429c73ef859",
          "default_preference": "opt_out",
          "current_preference": "opt_in",
          "outdated_preference": null,
          "current_served": true,
          "outdated_served": null
        }
      ]
    }
  ],
  "total": 1,
  "page": 1,
  "size": 50
}
[
  {
    "name": "new_name",
    "id": "pri_8673c052-419a-4862-acee-410a8ade45a5"
  }
]
  • Now that when you GET experiences, the notice returns that an outdated version of the notice was served to the user, and that we have an outdated preference saved as well

GET http://localhost:8080/api/v1/privacy-experience?show_disabled=true&region=us_ca&fides_user_device_id=3e2e5f7c-5367-47d4-b672-9427626c71db
Truncated Response:

{
  "items": [
    {
      "region": "us_ca",
      "component": "overlay",
      "experience_config": {},
      "id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
      "created_at": "2023-07-06T13:28:35.171060+00:00",
      "updated_at": "2023-07-06T13:28:35.171060+00:00",
      "show_banner": true,
      "privacy_notices": [
        {
          "regions": [
            "us_ca"
          ],,
          "privacy_notice_history_id": "pri_52008ca3-406e-420f-8509-9429c73ef859",
          "default_preference": "opt_out",
          "current_preference": null,
          "outdated_preference": "opt_in",
          "current_served": null,
          "outdated_served": true
        }
      ]
    }
  ],
  "total": 1,
  "page": 1,
  "size": 50
}
  • There are separate endpoints for the privacy center, as these endpoints also let you record consent against verified identities like email and phone number. Create a consent request and note the returned consent_request_id.
    POST http://localhost:8080/api/v1/consent-request
{
  "email": "[email protected]",
  "fides_user_device_id": "3e2e5f7c-5367-47d4-b672-9427626c71db"
}
{
  "browser_identity": {
    "fides_user_device_id": "3e2e5f7c-5367-47d4-b672-9427626c71db"
  },
  "privacy_notice_history_ids": [
    "pri_52008ca3-406e-420f-8509-9429c73ef859"
  ],
  "privacy_experience_id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
  "user_geography": "us_ca",
  "acknowledge_mode": false,
  "serving_component": "privacy_center"
}
{
  "browser_identity": {
    "fides_user_device_id": "3e2e5f7c-5367-47d4-b672-9427626c71db"
  },
  "preferences": [
    {
      "privacy_notice_history_id": "pri_52008ca3-406e-420f-8509-9429c73ef859",
      "preference": "opt_in",
      "served_notice_history_id": "ser_64565af7-0686-4e69-9100-352d1d11dfce"
    }
  ],
  "policy_key": "default_consent_policy",
  "privacy_experience_id": "pri_6ec7166a-28a8-49d9-9984-9b429d393d11",
  "user_geography": "us_ca",
  "method": "button"
}

Pre-Merge Checklist

  • All CI Pipelines Succeeded
  • Documentation:
  • Issue Requirements are Met
  • Relevant Follow-Up Issues Created
  • Update CHANGELOG.md
  • For API changes, the Postman collection has been updated Postman is not working on my machine at all at the moment, I've spent too much time trying to get this up and running

…are many fields with PrivacyPreferenceHistory and CurrentPrivacyPreference. These tables track every time a notice was served in the frontend for a given user, and then the last time a notice was served for a user.

- Update GET /privacy-experience to declare on the notice if it was served to an end user or if an older version has been served
…I when notices are served. Multiple notices that were served together should be sent in the same request.
…y center. This endpoint has logic capable of handling multiple identity types, such as an email and a fides user device id.
@cypress
Copy link

cypress bot commented Jul 11, 2023

Passing run #3160 ↗︎

0 4 0 0 Flakiness 0
⚠️ You've recorded test results over your free plan limit.
Upgrade your plan to view test results.

Details:

Merge 6ea818a into 49fe64c...
Project: fides Commit: 7b6d8e0e6e ℹ️
Status: Passed Duration: 01:00 💡
Started: Jul 13, 2023 6:14 PM Ended: Jul 13, 2023 6:15 PM

This comment has been generated by cypress-bot as a result of this project's GitHub integration settings.

@codecov
Copy link

codecov bot commented Jul 11, 2023

Codecov Report

Patch coverage: 100.00% and project coverage change: +0.10 🎉

Comparison is base (369c789) 87.16% compared to head (6ea818a) 87.27%.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3777      +/-   ##
==========================================
+ Coverage   87.16%   87.27%   +0.10%     
==========================================
  Files         311      311              
  Lines       19060    19222     +162     
  Branches     2462     2470       +8     
==========================================
+ Hits        16614    16776     +162     
  Misses       2018     2018              
  Partials      428      428              
Impacted Files Coverage Δ
src/fides/api/db/base.py 100.00% <ø> (ø)
...i/api/v1/endpoints/privacy_preference_endpoints.py 98.52% <100.00%> (+0.49%) ⬆️
src/fides/api/models/privacy_experience.py 99.45% <100.00%> (+0.03%) ⬆️
src/fides/api/models/privacy_notice.py 98.79% <100.00%> (+0.01%) ⬆️
src/fides/api/models/privacy_preference.py 100.00% <100.00%> (ø)
src/fides/api/schemas/privacy_notice.py 100.00% <100.00%> (ø)
src/fides/api/schemas/privacy_preference.py 100.00% <100.00%> (ø)
src/fides/api/util/consent_util.py 99.41% <100.00%> (ø)
src/fides/cli/options.py 93.40% <100.00%> (ø)
src/fides/common/api/v1/urn_registry.py 100.00% <100.00%> (ø)

☔ View full report in Codecov by Sentry.
📢 Do you have feedback about the report comment? Let us know in this issue.

@pattisdr pattisdr marked this pull request as ready for review July 12, 2023 18:46
@pattisdr
Copy link
Contributor Author

@allisonking when you have time, could you add the bit on the frontend that calls the new endpoints to record that consent was served? there are two endpoints, one for the privacy center, and one for banners/overlay. The response for these will return a "served_notice_history_id" for each notice that was served. Then you can take that id and pass it into the backend when saving preferences if applicable, to link those two records together.

We can reticket too if you prefer, and I will hold off on merging this until we've tested this end to end -

@allisonking
Copy link
Contributor

@allisonking when you have time, could you add the bit on the frontend that calls the new endpoints to record that consent was served? there are two endpoints, one for the privacy center, and one for banners/overlay. The response for these will return a "served_notice_history_id" for each notice that was served. Then you can take that id and pass it into the backend when saving preferences if applicable, to link those two records together.

We can reticket too if you prefer, and I will hold off on merging this until we've tested this end to end -

Thanks @pattisdr ! I think we should make a separate ticket for the frontend since the change is nontrivial. I talked to @rsilvery who is going to confirm if it's okay for the frontend ticket to go in the next sprint (ticket here: #3780)

Copy link
Contributor

@allisonking allisonking left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks great! I'll test it out further once I'm actually integrating with it :)

@pattisdr
Copy link
Contributor Author

Thanks @pattisdr ! I think we should make a separate ticket for the frontend since the change is nontrivial. I talked to @rsilvery who is going to confirm if it's okay for the frontend ticket to go in the next sprint (ticket here: #3780)

Thank you Allison! I responded to your comments - I'll go ahead and merge this I actually moved a lot of stuff around that I want to build off with TCF so I think we can just get this in there, and start writing to it later.

@pattisdr pattisdr merged commit dacba24 into main Jul 13, 2023
@pattisdr pattisdr deleted the fides_3006_record_when_consent_is_served branch July 13, 2023 21:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Backend] Record Each Time Consent Is Served
2 participants